// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_TESTS_BOOST_XML_TESTS_H_
#define LIBV_TESTS_BOOST_XML_TESTS_H_

#include <gtest/gtest.h>
#include <libv/xml.h>



namespace libv {
namespace tests {

class XmlDocumentTests : public ::testing::Test {
  protected:
    virtual void SetUp() {}
    virtual void TearDown() {}

    ::std::string ParseValue(const ::std::string& tag_value) {
        ::std::string xml;
        xml.append("<test>");
        xml.append(tag_value);
        xml.append("</test>");
        return libv::XmlDocument(xml).Child("test").Value();
    }

    ::std::string ParseValuePreserve(const ::std::string& tag_value) {
        ::std::string xml;
        xml.append("<test xml:space='preserve'>");
        xml.append(tag_value);
        xml.append("</test>");
        return libv::XmlDocument(xml).Child("test").Value();
    }

    ::std::string ParseValueOdt(const ::std::string& tag_value) {
        ::std::string xml;
        xml.append("<text:p>");
        xml.append(tag_value);
        xml.append("</text:p>");
        return libv::XmlDocument::Parse<
                  libv::XmlDocument::parse_odt
               >(xml).Child("text:p").Value();
    }
};



// In conformance with the W3C XML specification [XML1.0], optional white-space
// characters that are contained in elements that have element content
// (in other words that must contain elements only but not text) are ignored.
// This applies to the following white-space and end-of-line characters:
//  - HORIZONTAL TABULATION (0x0009)
//  - LINE FEED (0x000A)
//  - CARRIAGE RETURN (0x000D)
//  - SPACE (0x0020).
// For any other element, white-spaces are preserved by default.

TEST_F(XmlDocumentTests, SimpleSpaceInDataNode) {
    EXPECT_STREQ("a b c", ParseValue("a b c").c_str());
    EXPECT_STREQ("a  b  c", ParseValue("a  b  c").c_str());

    EXPECT_STREQ(" a b c ", ParseValue(" a b c ").c_str());
    EXPECT_STREQ("  a b c  ", ParseValue("  a b c  ").c_str());

    EXPECT_STREQ("\r\n\ta b c\r\n\t", ParseValue("\r\n\ta b c\r\n\t").c_str());
}

TEST_F(XmlDocumentTests, ContainsDataNodes) {
    EXPECT_STREQ(" a b c ", ParseValue(" a b c <x></x>").c_str());
    EXPECT_STREQ(" a b c ", ParseValue("<x></x> a b c <y></y>").c_str());
}

TEST_F(XmlDocumentTests, SpaceForIdentation) {
    EXPECT_STREQ("", ParseValue(" \r\n\t<x></x>").c_str());
}

TEST_F(XmlDocumentTests, XmlSpacePreserve) {
    EXPECT_STREQ("  a b c  ", ParseValuePreserve("  a b c  ").c_str());
    EXPECT_STREQ(" \r\n\t", ParseValuePreserve(" \r\n\t<x></x>").c_str());
}



// If the paragraph element or any of its child elements contains white-space
// characters, they are collapsed. Leading white-space characters
// at the paragraph start as well as trailing white-space characters
// at the paragraph end are ignored.
// ...
// White-space processing takes place within the following elements:
//  - <text:p>
//  - <text:h>
//  - <text:span>
//  - <text:a>
//  - <text:ref-point>
//  - <text:ref-point-start>
//  - <text:ref-point-end>
//  - <text:bookmark>
//  - <text:bookmark-start>
//  - <text:bookmark-end>.
// Все эти правила в парсере реализовывать нет смысла, так как в основном они
// относятся к процессу создания XML, а не чтения. OpenOffice заменяет только
// начальный пробел на <text:space>, а конечный нарушает описанные выше правила.
// Поэтому флаг parse_odt_document обозначает неявный атрибут
// xml:space='preserve' для заданных выше тегов.

TEST_F(XmlDocumentTests, NoOdt) {
    EXPECT_STREQ("", ParseValue("<span></span> <span></span>").c_str());
    EXPECT_STREQ(" ",ParseValuePreserve("<span></span> <span></span>").c_str());
}

TEST_F(XmlDocumentTests, Odt) {
    EXPECT_STREQ(" ", ParseValueOdt(" ").c_str());
    EXPECT_STREQ(" \r\t\na b c ", ParseValueOdt(" \r\t\na b c ").c_str());

    EXPECT_STREQ(" a ", ParseValueOdt("<span></span> a <span></span>").c_str());
    EXPECT_STREQ(" ", ParseValueOdt("<span></span> <span></span>").c_str());
}

}  // tests
}  // libv

#endif  // LIBV_TESTS_BOOST_XML_TESTS_H_